package es.uned.etsii.si3.taller.servlets;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;
import com.opensymphony.xwork2.ActionSupport;

import es.uned.etsii.si3.taller.*;
import es.uned.etsii.si3.taller.misc.ProporcionaFuncionalidad;

public class PTListados extends ActionSupport implements SessionAware {
	
	private static final long serialVersionUID = 1L;

	private 	Map<String, Object>	userSession;
	public 		Usuario 			getUsuario() 							{ return (Usuario) userSession.get("usuario"); }
	
	private 	Cliente  			clienteSeleccionado;
	public 		Cliente 	 		getClienteSeleccionado() 				{ return this.clienteSeleccionado; }
	public 		void      			setClienteSeleccionado(Cliente c) 		{ this.clienteSeleccionado = c; }

	private 	Vehiculo  			vehiculoSeleccionado;
	public 		Vehiculo 	 		getVehiculoSeleccionado() 				{ return this.vehiculoSeleccionado; }
	public 		void      			setVehiculoSeleccionado(Vehiculo v)		{ this.vehiculoSeleccionado = v; }

	private 	Trabajo				trabajoSeleccionado = null;
	public 		Trabajo				getTrabajoSeleccionado() 				{ return this.trabajoSeleccionado; }
	public 		void				setTrabajoSeleccionado(Trabajo t) 		{ this.trabajoSeleccionado = t; }

	private 	static int			vehiculoSeleccionadoID = -1;
	public 		int 				getVehiculoSeleccionadoID() 			{ return PTListados.vehiculoSeleccionadoID; }
	public 		void				setVehiculoSeleccionadoID(int i) 		{ PTListados.vehiculoSeleccionadoID = i; }

	private 	static int 			trabajoSeleccionadoID = -1;
	public 		int					getTrabajoSeleccionadoID() 				{ return PTListados.trabajoSeleccionadoID; }
	public 		void				setTrabajoSeleccionadoID(int i) 		{ PTListados.trabajoSeleccionadoID = i; }
	
	private 	ParteTrabajo		parteSeleccionado = null;
	public 		ParteTrabajo		getParteSeleccionado() 					{ return this.parteSeleccionado; }
	public 		void				setParteSeleccionado(ParteTrabajo pT) 	{ this.parteSeleccionado = pT; }

	private 	List<ParteTrabajo> 	listado = null;
	public 		List<ParteTrabajo>	getListado() 							{ return this.listado; }
	public 		void 				setListado(List<ParteTrabajo> l) 		{ this.listado = l; }

	private 	List<Trabajo> 		listadoTrabajos = null;
	public 		List<Trabajo>	 	getListadoTrabajos()					{ return this.listadoTrabajos; }
	public 		void 				setListadoTrabajos(List<Trabajo> l)		{ this.listadoTrabajos = l; }
	
	private		List<Reparacion>	listadoReparaciones = null;
	public		List<Reparacion>	getListadoReparaciones()				{return this.listadoReparaciones; }
	public		void				setListadoReparaciones(List<Reparacion> rp)	{this.listadoReparaciones = rp; }

	private 	List<MaterialTrabajo> listadoMaterialTrabajos = null;
	public 		List<MaterialTrabajo> getListadoMaterialTrabajos()			{ return this.listadoMaterialTrabajos; }
	public 		void 				  setListadoMaterialTrabajos(List<MaterialTrabajo> l)		{ this.listadoMaterialTrabajos = l; }
	
	private		List<Vehiculo>		listadoVehiculos = null;
	public		List<Vehiculo>		getListadoVehiculos()					{ return this.listadoVehiculos; }
	public		void				setListadoVehiculos(List<Vehiculo> vh)	{ this.listadoVehiculos = vh; }
	
	private		int					parteTrabajoSel = -1;
	public		int					getParteTrabajoSel()					{ return this.parteTrabajoSel; }
	public		void				setParteTrabajoSel(int ps)			{ this.parteTrabajoSel = ps; }

	
/** 
 * Obtiene la lista de partes de trabajo que aun no han sido aceptados por el cliente
 * @return  actionerror
 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.USUARIO_PRESUPUESTOS_PENDIENTES)	
	public String generarListadoPresupuestos() {
		try {			
			QueryBuilder<ParteTrabajo, Integer> parteQb = FactoriaDAO.getDao(ParteTrabajo.class).queryBuilder();			
			Where<ParteTrabajo, Integer> whereParteQb = parteQb.where();			
			whereParteQb.eq(ParteTrabajo.ID_USUARIO_FIELD_NAME, this.getUsuario());			
			whereParteQb.and().eq(ParteTrabajo.ACEPTADO_FIELD_NAME, false);
			listado = whereParteQb.query();
		}
		catch (SQLException e) {
			addActionError("Error al crear el listado de Presupuestos pendientes: " + e);
		}		
		return SUCCESS;
	}
    
	/** 
	 * Muestra el estado de los vehículos en taller
	 * @return  actionerror
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.USUARIO_PRESUPUESTOS_PENDIENTES)	
	public String generarListadoReparaciones() {
		try {			
			// Obtebemos el cliente actual
			this.setClienteSeleccionado(this.getUsuario().getCliente());			
			
			// Obtenemos los vehículos del usuario y lo mergeamos con la tabla de vehículos
			QueryBuilder<VehiculoUsuario, Integer> vuQb = FactoriaDAO.getDao(VehiculoUsuario.class).queryBuilder();
			vuQb.where().eq(VehiculoUsuario.ID_USUARIO_FIELD_NAME, this.getUsuario());
			QueryBuilder<Vehiculo, Integer> vehiculoQb = FactoriaDAO.getDao(Vehiculo.class).queryBuilder();
			this.listadoVehiculos = vehiculoQb.join(vuQb).query();
			
			// Obtenemos todos los partes de trabajo que hay ahora mismo en activo para el cliente, es decir, aquellos que no tiene fechasalida
			QueryBuilder<ParteTrabajo, Integer> parteQb = FactoriaDAO.getDao(ParteTrabajo.class).queryBuilder();
			parteQb.where().eq(ParteTrabajo.ID_USUARIO_FIELD_NAME, this.getUsuario())
				.and().isNull(ParteTrabajo.FECHASALIDA_FIELD_NAME);
			this.listado = parteQb.join(vehiculoQb).query();
		}
		catch (SQLException e) {
			addActionError("Error al crear el crear el listado de Reparaciones en curso: " + e);
		}		
		return SUCCESS;
	}

		/**
		 * Obtenemos los datos del detalle del parte
		 * @return  actionerror
		 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.USUARIO_VEHICULOS_EN_TALLER)	
	public String cliDetalleParte() {
		String res = SUCCESS;
		try {
			// Recuperamos el parte de trabajo a mostrar
			parteSeleccionado = FactoriaDAO.recuperar(ParteTrabajo.class, parteTrabajoSel);
			
			// Obtenemos todas las reparaciones
			QueryBuilder<Reparacion, Integer> repQb = FactoriaDAO.getDao(Reparacion.class).queryBuilder();
			repQb.where().eq(Reparacion.ID_PARTETRABAJO_FIELD_NAME, parteTrabajoSel);
			listadoReparaciones = repQb.query();
			// Obtenemos todos los trabajos
			
			QueryBuilder<Trabajo, Integer> trabQb = FactoriaDAO.getDao(Trabajo.class).queryBuilder();
			listadoTrabajos = trabQb.join(repQb).query();
			
			// Obtenemos todos los materiales
			QueryBuilder<MaterialTrabajo, Integer> matQb = 
					FactoriaDAO.getDao(MaterialTrabajo.class).queryBuilder();
			listadoMaterialTrabajos = matQb.join(trabQb).query();
			
		} catch (SQLException e) {
			addActionError("Error de base de datos: " + e);
			res = ERROR;
		}
		return res;
	
	}
	
	/**
	 * Obtenemos los datos de la recepción
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.USUARIO_VEHICULOS_EN_TALLER)	
	public String  pTDetalleReparacionActual() throws SQLException {
		String res = SUCCESS;		
		this.cargarDatosPrevios();
		QueryBuilder<ParteTrabajo, Integer> parJOINveh = this.getParteVehiculoQb();
		QueryBuilder<Reparacion, Integer> repJOINsec = this.getReparacionSeccionQb();
		QueryBuilder<Trabajo, Integer> traJOINmat = this.getTrabajoMaterialQb();
		this.listadoTrabajos = traJOINmat.join((repJOINsec).join(parJOINveh))
								.orderBy(Trabajo.FECHAFIN_FIELD_NAME, false).distinct().query();
		return res;
	}

	private QueryBuilder<Trabajo, Integer> getTrabajoMaterialQb() throws SQLException {
		QueryBuilder<Trabajo, Integer> trabajoQb = FactoriaDAO.getDao(Trabajo.class).queryBuilder();
		
		QueryBuilder<MaterialTrabajo, Integer> materialTrabajoQb = FactoriaDAO.getDao(MaterialTrabajo.class).queryBuilder();			
		QueryBuilder<Material, Integer> materialQb = FactoriaDAO.getDao(Material.class).queryBuilder();
		QueryBuilder<MaterialTrabajo, Integer> mtJOINmat = materialTrabajoQb.join(materialQb);
		return trabajoQb;
	}
	private QueryBuilder<Reparacion, Integer> getReparacionSeccionQb() throws SQLException {
		QueryBuilder<Seccion, Integer> seccionQb = FactoriaDAO.getDao(Seccion.class).queryBuilder();
		QueryBuilder<TipoSeccion, Integer> tipoSeccionQb = FactoriaDAO.getDao(TipoSeccion.class).queryBuilder();
		QueryBuilder<Seccion, Integer> secJOINtip = seccionQb.join(tipoSeccionQb);
		
		QueryBuilder<Reparacion, Integer> reparacionQb = FactoriaDAO.getDao(Reparacion.class).queryBuilder();
		return reparacionQb.join(secJOINtip);
	}
	
	private QueryBuilder<ParteTrabajo, Integer> getParteVehiculoQb() throws SQLException {
		QueryBuilder<Vehiculo, Integer> vehiculoQb = FactoriaDAO.getDao(Vehiculo.class).queryBuilder();		
		QueryBuilder<ParteTrabajo, Integer> parteQb = FactoriaDAO.getDao(ParteTrabajo.class).queryBuilder();			
		Where<ParteTrabajo, Integer> whereParteQb = parteQb.where();					
		whereParteQb.eq(ParteTrabajo.ID_USUARIO_FIELD_NAME, this.getUsuario());
		whereParteQb.and().eq(ParteTrabajo.ID_VEHICULO_FIELD_NAME, this.getVehiculoSeleccionado());
		whereParteQb.and().eq(ParteTrabajo.VISTOBUENO_FIELD_NAME, false);
		return parteQb.join(vehiculoQb);
	}
	
	private void cargarDatosPrevios() throws SQLException {
		//Trabajo
		this.setTrabajoSeleccionadoID(this.getTrabajoSeleccionadoID());		
		this.setTrabajoSeleccionado(FactoriaDAO.recuperar(Trabajo.class, this.getTrabajoSeleccionadoID()));
		//Vehiculo
		this.setVehiculoSeleccionado(this.getTrabajoSeleccionado().getReparacion().getParteTrabajo().getVehiculo());
		this.setVehiculoSeleccionadoID(this.getVehiculoSeleccionado().getId());
		this.setVehiculoSeleccionado(FactoriaDAO.recuperar(Vehiculo.class, this.getVehiculoSeleccionadoID()));
		//Cliente
		this.setClienteSeleccionado(this.getUsuario().getCliente());

	}

	@Override
	public void setSession(Map<String, Object> session) {
		userSession = session;		
	}

}
